/*
 * @Author: jiaqiang.li
 * @Date: 2022-06-21 13:39:23
 * @LastEditTime: 2022-06-21 15:17:26
 * @Description: file content
 */
#include "sys_task_base.h"
#include "main.h"
#include "string.h"
#include "timers.h"
#include "stdlib.h"


osMessageQueueId_t osMessageQueueId;
osSemaphoreId_t mcOsSemaphoreId;
#define SS_TASK_MESSAGEQ_SIZE 50
#define MAX_TASK_NUM        50
TaskStatus_t pxTaskStatusArray[MAX_TASK_NUM];

void base_task_init(void) {
    osMessageQueueId = osMessageQueueNew(SS_TASK_MESSAGEQ_SIZE, sizeof(ssMsg_t), NULL);//Space(Bytes)=92+(ElemSize * nElem)
		mcOsSemaphoreId = osSemaphoreNew(1, 1, NULL);
		osSemaphoreRelease(mcOsSemaphoreId);
}

ssMsg_t *createMsg(uint8_t type, void *data, uint32_t len) {
    ssMsg_t *msg = {0};
    uint32_t size = 0;
    msg->type = type;
    size = len * sizeof(uint8_t);
    memcpy(msg->data, data, size);
    msg->length = len;

    return msg;
}
_Bool SS_MsgPut(SS_MsgType_t type, void *data, uint32_t len) {
    ssMsg_t msg = {0};
		if(len > 32) return FALSE;
		
    osStatus_t state;
    msg.type = type;
		msg.length = len;
		memset(msg.data, 0, 32);
		if(NULL != data)
		{
				memcpy(msg.data, data, len * sizeof(uint8_t));
		}

    state = osMessageQueuePut(osMessageQueueId, (void *)&msg, 0, 0);
    if (state != osOK) {
        return FALSE;
    }
		state = osSemaphoreAcquire(mcOsSemaphoreId, 0);
		if(state != osOK)
		{
			printf("error: take semaphore fail of SS_MsgPut.\r\n");
		}
    return TRUE;
}

uint16_t ss_strlen(const uint8_t *str) {
    uint16_t i = 0;
    if (NULL == str) return i;

    while (*(str++) != '\0') {
        i += 1;
    }
    return i;
}
int32_t ss_Find(uint8_t *s1, const uint8_t *s2, uint16_t len) {
    int16_t index = 0;
    uint8_t len_s2 = ss_strlen(s2);

    if (ss_strlen(s1) == 0 || len_s2 == 0) return index;

    for (; *s1 && len > 0; ++s1, len--) {
        if (*s1 == *s2 && strncmp((const char *)s1, (const char *)s2, len_s2) == 0) return index;
        index += 1;
    }
    return -1;
}

void init_timer1_for_runtime_state(void)
{
		TimerHandle_t xTimer = xTimerCreate( "getTasksInfo",         
                            pdMS_TO_TICKS(1),//1ms
                            (UBaseType_t)pdTRUE,
                             (void*)1,
                            NULL );
		xTimerStart( xTimer, 0 );
}
//get os task information
void get_task_state(int32_t argc,void *cmd_arg)
{
    const char task_state[]={'r','R','B','S','D'};
    volatile UBaseType_t uxArraySize, x;
    uint32_t ulTotalRunTime,ulStatsAsPercentage;
 
    //get tasks count
    uxArraySize = uxTaskGetNumberOfTasks();
   if(uxArraySize>MAX_TASK_NUM)
    {
        printf("task count over max\n");
    }
 
    /*get every task information*/
    uxArraySize = uxTaskGetSystemState(pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
 
    #if (configGENERATE_RUN_TIME_STATS==1)
   
    printf("task 			state  ID    Priority  heap/stack    CPU used\n");
 
    if( 1 || ulTotalRunTime > 0 )
    {
        for( x = 0; x < uxArraySize; x++ )
        {
            char tmp[128];
           
            /*Calculate task runtime as a percentage of total runtime*/
            ulStatsAsPercentage =(uint64_t)(pxTaskStatusArray[ x ].ulRunTimeCounter)*100 / ulTotalRunTime;
 
            if( ulStatsAsPercentage > 0UL )
            {
 
               sprintf(tmp,"%-12s%-6c%-6d%-8d%-8d%d%%",pxTaskStatusArray[ x].pcTaskName,task_state[pxTaskStatusArray[ x ].eCurrentState],
                                                                       (int)pxTaskStatusArray[ x ].xTaskNumber,(int)pxTaskStatusArray[ x].uxCurrentPriority,
                                                                       pxTaskStatusArray[ x ].usStackHighWaterMark,ulStatsAsPercentage);
            }
            else
            {
                sprintf(tmp,"%-12s%-6c%-6d%-8d%-8dt<1%%",pxTaskStatusArray[x ].pcTaskName,task_state[pxTaskStatusArray[ x ].eCurrentState],
                                                                       (int)pxTaskStatusArray[ x ].xTaskNumber,(int)pxTaskStatusArray[ x].uxCurrentPriority,
                                                                       pxTaskStatusArray[ x ].usStackHighWaterMark);               
            }
           printf("%s\n",tmp);
        }
    }
    printf("task state:   r-run  R-ready  B-Blocking  S-suspend  D-Delete\n");
    #endif //#if (configGENERATE_RUN_TIME_STATS==1)
}